import math
import numpy as np
import scipy.io
from .Getft import Getft
from .D2Beta_2 import D2Beta_2
from .S2Beta_3 import S2Beta_3


def Parameters(num_symbols, bits_per_symbol, total_baud, up_sampling_factor, sampling_rate, npol, span, L, delta_z,
               alpha, beta2, gamma):
    ''' ============================================= 设定信号参数 =============================================================='''
    Signal_Para = {}
    # 发送码元数
    Signal_Para['Symbol_number'] = num_symbols  # The number of symbols
    # 信号调制格式 2-QPSK/4QAM  4-16QAM  5-32QAM  6-64QAM
    Signal_Para['Bits_per_symbol'] = bits_per_symbol  # 2-QPSK/4QAM  4-16QAM  5-32QAM  6-64QAM
    # 以下ls
    Signal_Para['total_Baud'] = total_baud  # Symbol Rate /Hz
    Signal_Para['up_sampling_factor'] = up_sampling_factor  # up-sampling factor
    Signal_Para['Sampling_rate'] = sampling_rate  # Sampling rate
    Signal_Para['C'] = 3e8  # m/s
    Signal_Para['polarization'] = npol  # 偏振数
    Signal_Para['lamda_wave'] = 1550
    Signal_Para['f_c'] = Signal_Para['C'] / (Signal_Para['lamda_wave'] * 1e-9)  # 中心频率  Hz
    Signal_Para['FFT_persym'] = Signal_Para['up_sampling_factor']
    Signal_Para['FFT_len'] = Signal_Para['Symbol_number'] * Signal_Para['FFT_persym']  # FFT数据长度，一般等于输入信号长度
    Signal_Para['Ft'] = Getft(Signal_Para)
    Signal_Para['f_omega'] = 2 * math.pi * Signal_Para['Ft']

    # 指定保存的文件名
    file_name = 'output.mat'
    # 使用 scipy.io.savemat() 函数保存字典变量到 MATLAB 文件
    scipy.io.savemat(file_name, {'Signal_Para': Signal_Para})

    Signal_Para['powerdBm_Set'] = 0  # 入纤光功率 dbm，每个信道的信号总功率
    Signal_Para['field'] = 'UNIQUE'
    ''' ============================================ 设定光纤参数 ================================================================= '''

    ''' ========================= 设定SSFM方法参数'''
    Fiber_Para = {}
    Fiber_Para['Span'] = span  # span个数
    Fiber_Para['L'] = L  # 每个span的长度：km
    Fiber_Para['step_size'] = delta_z  # 每个span的操作长度 km
    Fiber_Para['stepnumber'] = Fiber_Para['L'] / Fiber_Para['step_size']  # 每个span的操作步数
    # Constant_step_size,Logarithmic_distribution_step,Nonlinear_phase_rotation,combine_LDS_and_NPR
    Fiber_Para['step_type'] = 'Constant_step_size'  # 选择步长构造方式
    Fiber_Para['ssfm_type'] = 'Asymmetric'  # 选择ssfm方式，1、Asymmetric。2、Symmetric。
    Fiber_Para['Equation'] = 'Manakov'  # 选择不同的方程仿真:Manakov, CNLSE
    Fiber_Para['Mode'] = 1
    Fiber_Para['i'] = 0  # 步数索引
    Fiber_Para['lambda'] = 1550
    ''' ========================= 设定衰减参数'''
    Fiber_Para['alpha_dB'] = alpha  # 衰减系数：dB/km
    Fiber_Para['alpha_km'] = math.log(10) * Fiber_Para['alpha_dB'] / 10  # [km^-1]

    ''' ========================= 设定群速度色散参数'''
    Fiber_Para['beta_1'] = 0
    # Fiber_Para['D'] = 17  # [ps/nm/km]
    Fiber_Para['D'] = 17  # [ps/nm/km]
    # Fiber_Para['beta_2'] = D2Beta_2(Signal_para=Signal_Para, Fiber_para=Fiber_Para)  # GVD：s^2/km
    Fiber_Para['beta_2'] = beta2
    # Fiber_Para['S'] = 0.057  # [ps/nm^2/km]
    Fiber_Para['S'] = 0  # [ps/nm^2/km]
    # Fiber_Para['beta_3'] = S2Beta_3(Signal_para=Signal_Para, Fiber_para=Fiber_Para)
    Fiber_Para['beta_3'] = 0

    ''' ========================= 设定非线性参数'''
    Fiber_Para['gamma'] = gamma  # 非线性系数：1/(W*km)
    Fiber_Para['n2I'] = 2.5e-20  # 非线性折射率系数 [m^2/W]
    Fiber_Para['Aeff'] = 80e-12

    # Fiber_Para = Parameter.My_Parameter(Fiber_Para)
    # Fiber_Para.load()
    ''' ============================================ 设定放大器参数 ================================================================= '''
    Amplifer_Para = {}
    Amplifer_Para['EDFA_nf_db'] = 5  # EDFA噪声系数：db
    Amplifer_Para['Amplifer_type'] = 'EDFA'

    # Amplifer_Para = Parameter.My_Parameter(Amplifer_Para)
    # Amplifer_Para.load()
    ''' ============================================ 设定PMD参数 =================================================================== '''
    PMD_Para = {}
    PMD_Para['PMD'] = 0  # PMD是否添加
    PMD_Para['beatlength'] = 20  # 拍长[m]
    PMD_Para['PMD_DGD'] = 0.05e-12  # DGD[s/Km^1/2]Span
    PMD_Para['trunk_num'] = 100  # 添加PMD时所分的trunk数
    PMD_Para['L_corr'] = Fiber_Para['L'] / PMD_Para['trunk_num']  # 添加PMD时所分的trunk长度
    '''------随机旋转矩阵-----'''
    # PMD_Para['Matrix'] = np.zeros((2, 2, PMD_Para['trunk_num']))
    PMD_Para['Matrix'] = np.zeros((2, 2, PMD_Para['trunk_num']), dtype='complex')
    # PMD_Para['Matrix'] = PMD_Para['Matrix'].astype('complex')
    PMD_Para['eigenvalue'] = np.zeros((PMD_Para['trunk_num'], 2))

    return Signal_Para, Fiber_Para, Amplifer_Para, PMD_Para
